<template>
  <div>
    <el-button
      @click="onTake"
      icon="el-icon-camera"
      size="small">
      拍照上传
    </el-button>
      
      <div class="box" width="1065px" height="1065px" style="vertical-align:middle;text-align:center">
        <div class="div-v">
        <video id="videoCamera"  class="canvas" :width="videoWidth" :height="videoHeight" :z-index="1" autoPlay></video>
        </div>        
        <div class="div-c">
        <canvas id="canvasCamera" align class="canvas" :width="videoWidth" :height="videoHeight" :z-index="2"></canvas>
        </div>
      </div>
      <div slot="footer">
        <el-button
          @click="drawImage"
          icon="el-icon-camera"
          size="small">

          拍照
        </el-button>
        <el-button
          v-if="open"
          @click="getCompetence"
          icon="el-icon-video-camera"
          size="small">
          打开摄像头
        </el-button>
        <el-button
          v-else
          @click="stopNavigator"
          icon="el-icon-switch-button"
          size="small">
          关闭摄像头
        </el-button>
        <el-button
          @click="resetCanvas"
          icon="el-icon-refresh"
          size="small">
          重置
        </el-button>
        <el-button
          @click="onCancel"
          icon="el-icon-circle-close"
          size="small">
          取消
        </el-button>
        <el-button
          @click="onUpload"
          :loading="loading"
          type="primary"
          icon="el-icon-upload2"
          size="small">
          上传
        </el-button>
      </div>
    
  </div>
</template>
 
<script>
  //拍照上传组件
  //父组件通过函数 getImg 获取照片路径,如 @getImg="getImg"
  const Address = require('../assets/polan.png');//图片上传地址
  export default {
    name: "TakePhotos",
    data() {
      return {
        imgSrc: "",
        visible: false,//弹窗
        loading: false,//上传按钮加载
        open: false,//控制摄像头开关
        vidd:1,
        canv:0,
        thisVideo: null,
        thisContext: null,
        thisCancas: null,
        videoWidth: 400,
        videoHeight: 400
      }
    },
    methods: {
      onTake() {
        this.visible = true;
        this.getCompetence();
      },
      onCancel() {
        this.visible = false;
        this.resetCanvas();
        this.stopNavigator();
      },
      //base64转成文件后上传
      onUpload() {
        if (this.imgSrc) {
          const file = this.imgSrc; // 把整个base64给file
          const time = (new Date()).valueOf();//生成时间戳
          const name = time + ".png"; // 定义文件名字（例如：abc.png ， cover.png）
          const conversions = this.dataURLtoFile(file, name); // 调用base64转图片方法
          const data = new FormData();
          data.append('file', conversions);
          const options = {
            method: "POST",   //请求方法
            body: data,   //请求体
            headers: {
              'Accept': 'application/json'
            },
          };
          this.loading = true;
          fetch(Address.UPLOAD, options)
            .then((response) => {
              return response.json();
            })
            .then((responseText) => {
              this.loading = false;
              if (responseText.code === 0) {
                this.imgSrc = responseText.data.src;
                this.$emit('getImg', responseText.data.src);//传递给父组件
                this.onCancel();
                this.$notify({
                  title: '上传成功',
                  message: responseText.msg,
                  type: 'success'
                });
              }
            })
            .catch((error) => {
              this.loading = false;
              this.$notify.error({
                title: '上传失败',
                message: error.msg,
              });
            })
        }
        else {
          this.$notify({
            title: '警告',
            message: '请点击拍照',
            type: 'warning'
          });
        }
      },
      // 调用摄像头权限
      getCompetence() {
        //必须在model中render后才可获取到dom节点,直接获取无法获取到model中的dom节点
        this.$nextTick(() => {
          const _this = this;
          this.open = false;//切换成关闭摄像头
          this.thisCancas = document.getElementById('canvasCamera');
          this.thisContext = this.thisCancas.getContext('2d');
          this.thisVideo = document.getElementById('videoCamera');
          // 旧版本浏览器可能根本不支持mediaDevices，我们首先设置一个空对象
          if (navigator.mediaDevices === undefined) {
            navigator.mediaDevices = {}
          }
          // 一些浏览器实现了部分mediaDevices，我们不能只分配一个对象
          // 使用getUserMedia，因为它会覆盖现有的属性。
          // 这里，如果缺少getUserMedia属性，就添加它。
          if (navigator.mediaDevices.getUserMedia === undefined) {
            navigator.mediaDevices.getUserMedia = function (constraints) {
              // 首先获取现存的getUserMedia(如果存在)
              let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia;
              // 有些浏览器不支持，会返回错误信息
              // 保持接口一致
              if (!getUserMedia) {
                return Promise.reject(new Error('getUserMedia is not implemented in this browser'))
              }
              // 否则，使用Promise将调用包装到旧的navigator.getUserMedia
              return new Promise(function (resolve, reject) {
                getUserMedia.call(navigator, constraints, resolve, reject)
              })
            }
          }
          const constraints = {
            audio: false,
            video: {width: _this.videoWidth, height: _this.videoHeight, transform: 'scaleX(-1)'}
          };
          navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
            // 旧的浏览器可能没有srcObject
            if ('srcObject' in _this.thisVideo) {
              _this.thisVideo.srcObject = stream
            } else {
              // 避免在新的浏览器中使用它，因为它正在被弃用。
              _this.thisVideo.src = window.URL.createObjectURL(stream)
            }
            _this.thisVideo.onloadedmetadata = function (e) {
              _this.thisVideo.play()
            }
          }).catch(err => {
            this.$notify({
              title: '警告',
              message: '没有开启摄像头权限或浏览器版本不兼容.',
              type: 'warning'
            });
          });
        });
      },
      //绘制图片
      drawImage() {
        // 点击，canvas画图
        this.thisContext.drawImage(this.thisVideo, 0, 0, this.videoWidth, this.videoHeight);
        // 获取图片base64链接
        this.imgSrc = this.thisCancas.toDataURL('image/png');
        document.decumentElement.style.setProperty('--dv',0);
      },
      //base64转文件
      dataURLtoFile(dataurl, filename) {
        let arr = dataurl.split(',');
        let mime = arr[0].match(/:(.*?);/)[1];
        let bstr = atob(arr[1]);
        let n = bstr.length;
        let u8arr = new Uint8Array(n);
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n)
        }
        return new File([u8arr], filename, {type: mime})
      },
      //清空画布
      clearCanvas(id) {
        let c = document.getElementById(id);
        let cxt = c.getContext("2d");
        cxt.clearRect(0, 0, c.width, c.height);
      },
      //重置画布
      resetCanvas() {
        this.imgSrc = "";
        this.clearCanvas('canvasCamera');
        document.decumentElement.style.setProperty('--dv',2);
      },
      //关闭摄像头
      stopNavigator() {
        if (this.thisVideo && this.thisVideo !== null) {
          this.thisVideo.srcObject.getTracks()[0].stop();
          this.open = true;//切换成打开摄像头
        }
      },
    },
    beforeDestroy() {
      this.stopNavigator()
    },
    mounted:function () {   //自动触发写入的函数
            this.onTake();
        }
  }
</script>
 
<style scoped>
  :root{
    --dv:2;
  }
  .box {
    display: flex;
    justify-content: space-between;
  }
 
  .canvas {
    border: 1px solid #5c0909 ;
    border-radius: 100%;
    
  }
  .div-v{ 
    position:absolute; 
    left:middle; 
    top:60px; 
    width:400px;
    height:200px;
    z-index: var(--dv);
  } 
  .div-c{ 
    position:absolute; 
    left:middle; 
    top:60px; 
    width:400px;
    height:200px;
    z-index: 1;
  } 
</style>



